const Controller = require('egg').Controller;

class ChatController extends Controller {
	// 连接socket
	async connect() {
		const { ctx, app, service } = this;
// 		let user_id = ctx.websocket.user_id;
		if (!ctx.websocket) {
			ctx.throw(400, '非法访问');
		}
		// console.log(`clients: ${app.ws.clients.size}`);
		// 监听接收消息和关闭socket
		ctx.websocket
		    .on('message', async msg => {
		        let user_id = ctx.websocket.user_id;
                if(!await this.service.cache.get('online_' + user_id)){
                    console.log('online_')
                 ctx.websocket.close();
                }
				console.log('接收消息', msg);
				if(msg == 'HeartBeat'){
				    ctx.websocket.send(JSON.stringify({msg}))
				}
				
			})
			.on('close', async (code, reason) => {
			    //console.log('close=========================app.ws.tmp_socket',app.ws.tmp_socket)
				// 用户下线
			
				let user_id = ctx.websocket.user_id;
				console.log('用户下线----',user_id, code, reason);
				// 移除redis用户上线记录
				// if(!app.ws.clearclear){
				    console.log('remove_online_用户下线')
				    //app.ws.clear = false
				  	service.cache.remove('online_' + user_id)
				    if (app.ws.user && app.ws.user[user_id]) {
					    delete app.ws.user[user_id];
				    }  
				// }
				// app.ws.clearclear = false
				console.log('在线人数：',Object.keys(app.ws.user).length)
			});

	}
	
	// 发送消息
	async send(){
		const { ctx, app } = this;
		// 拿到当前用户id
		let current_user_id = ctx.authUser.id;
		if(!this.service.cache.get('online_' + current_user_id)){
		    ctx.websocket.close()
		    return ctx.apiFail('您已离线')
		}
		// 验证参数
		ctx.validate({
			to_id: {
					type: 'int',
					required: true,
					desc: '接收人/群id'
			},
			chat_type: {
					type: 'string',
					required: true,
					range: {
							in: ['user', 'group']
					},
					desc: '接收类型'
			},
			type: {
					type: 'string',
					required: true,
					range: {
							in: ['text', 'image', 'video', 'audio', 'emoticon', 'card']
					},
					desc: '消息类型'
			},
			data: {
					type: 'string',
					required: true,
					desc: '消息内容'
			},
			options: {
					type: 'string',
					required: true
			}
		});
		let { to_id, chat_type, type, data, options } = ctx.request.body
		// 单聊
		if(chat_type === 'user'){
			// 验证好友是否存在，没有把你拉黑
			let friend = await app.model.Friend.findOne({
				where: {
					// 对方列表有没有自己
					user_id: to_id,
					friend_id: current_user_id,
          isblack: 0
				},
				include:[{
					model: app.model.User,
					as: 'userInfo'
				},
				{
					model: app.model.User,
					as: "friendInfo"
				}]
			})
			if(!friend) ctx.throw(400, '好友不存在或把你拉黑了')
			// 好友是否禁用(status为0)
			if(!friend.userInfo.status) ctx.throw(400, '好友已被禁用')
			
			// 构建消息格式
			// 发送者用户名
			let from_name = friend.friendInfo.nickname ? friend.friendInfo.nickname : friend.friendInfo.username;
			// 好友备注了用备注名
			if (friend.nickname) from_name = friend.nickname; 
			let message = {
				// 唯一id，后端生成唯一id
				id: (new Date()).getTime(), 
				// 发送者头像
				from_avatar: friend.friendInfo.avatar,
				// 发送者昵称
				from_name, 
				// 发送者id
				from_id: current_user_id, 
				// 接收人/群 id
				to_id, 
				// 接收人/群 名称
				to_name: friend.userInfo.nickname ? friend.userInfo.nickname : friend.userInfo.username, 
				// 接收人/群 头像
				to_avatar: friend.userInfo.avatar,
				 // 接收类型
				chat_type: 'user',
				 // 消息类型
				type,
				// 消息内容
				data, 
				options: {}, // 其他参数
				// 创建时间
				create_time: (new Date()).getTime(), 
				// 是否撤回
				isremove: 0, 
			}
			/*// 拿到对方socket
			let socket = app.ws.user[to_id]
			// 对方是否在线
			if(!socket){
				// 加入redis缓存中
				this.service.cache.setList('getMessage_'+to_id, message)
			}else{
				socket.send(JSON.stringify({
						msg: 'ok',
						data: message
				}))
				// 存到历史记录中
				this.service.cache.setList(`chatlog_${to_id}_${message.chat_type}_${current_user_id}`, message)
			}*/
			// 视频，截取封面图
			if(message.type == 'video'){
				message.options.poster = message.data + '?x-oss-process=video/snapshot,t_10000,m_fast,w_300,f_png'
			}
			// 音频,带上音频时长
			if(message.type == 'audio'){
				options = JSON.parse(options);
				message.options.time = options.time || 1
			}
			// 名片
			if(message.type == 'card'){
				// 可以验证名片用户是否存在
				message.options = JSON.parse(options)
			}
			ctx.sendAndSaveMessage(to_id, message);
			// 存到自己记录中
			this.service.cache.setList(`chatlog_${current_user_id}_${message.chat_type}_${to_id}`, message)
			// ctx.body = message
			return ctx.apiSuccess(message)
		}
		// 群聊
		let group = await app.model.Group.findOne({
			where: {
				status: 1,
				id: to_id
			},
			include: [{
				model: app.model.GroupUser,
				attributes: ['user_id', 'nickname']
			}]
		})
		if(!group) ctx.apiFail('该群聊不存在或已被封禁')
		// 当前用户是否在此群聊中
		let index = group.group_users.findIndex(item => item.user_id == current_user_id)
		if(index == -1) ctx.apiFail('你不在群聊中了');
		// 组织数据格式 发送者昵称
		let from_name = group.group_users[index].nickname;
		let message = {
			// 唯一id，后端生成唯一id
			id: (new Date()).getTime(), 
			// 发送者头像
			from_avatar: ctx.authUser.avatar,
			// 发送者昵称
			from_name: from_name || ctx.authUser.nickname || ctx.authUser.username, 
			// 发送者id
			from_id: current_user_id, 
			// 接收人/群 id
			to_id, 
			// 接收人/群 名称
			to_name: group.name, 
			 // 接收人/群 头像
			to_avatar: group.avatar,
			// 接收类型
			chat_type: 'group', 
			// 消息类型
			type,
			// 消息内容
			data, 
			// 其他参数
			options: {}, 
			// 创建时间
			create_time: (new Date()).getTime(), 
			// 是否撤回
			isremove: 0, 
			group: group
		}
		// 视频，截取封面图
		if(message.type == 'video'){
			message.options.poster = message.data + '?x-oss-process=video/snapshot,t_10000,m_fast,w_300,f_png'
		}
		// 音频,带上音频时长
		if(message.type == 'audio'){
			options = JSON.parse(options);
			message.options.time = options.time || 1
		}
		// 名片
		if(message.type == 'card'){
			// 可以验证名片用户是否存在
			message.options = JSON.parse(options)
		}
		// 推送
		group.group_users.forEach(item => {
			// 自己不推送
			if(item.user_id != current_user_id) {
				ctx.sendAndSaveMessage(item.user_id, message)
			}
		})
		ctx.apiSuccess(message)
	}
	
	// 获取离线消息
	async getmessage() {
			const { ctx, app, service } = this;
			let current_user_id = ctx.authUser.id;
			let key = 'getmessage_' + current_user_id;
			let list = await service.cache.getList(key);
			// 清除离线消息
			await service.cache.remove(key);
			// 批量推送
			list.forEach(async (message) => {
					// message转成对象
					let d = JSON.parse(message);
					ctx.sendAndSaveMessage(current_user_id, d.message, d.msg);
			});
	}

	// 撤回
	async recall(){
		const { ctx, app, service } = this;
		let current_user_id = ctx.authUser.id;
		ctx.validate({
			to_id: {
				type: 'int',
				required: true,
				desc: '接收人/群id'
			},
			chat_type: {
				type: 'string',
				required: true,
				range: {
						in: ['user', 'group']
				},
				desc: '接收类型'
			},
			id: {
				type: 'int',
				required: true,
				desc: '消息id'
			}
		});
		let { to_id, chat_type, id } = ctx.request.body;
		let message = {
			from_id: current_user_id,
			to_id,
			chat_type,
			id
		}
		// 单聊
		if (chat_type === 'user') {
			ctx.sendAndSaveMessage(to_id, message, 'recall');
			return ctx.apiSuccess(message);
		}
		// 群聊
		let group = await app.model.Group.findOne({
			where: {
				id: to_id,
				status: 1
			},
			include: [{
				model: app.model.GroupUser,
				attributes: ['user_id']
			}]
		});

		if (group) {
			group.group_users.forEach(item => {
				if (item.user_id !== current_user_id) {
					ctx.sendAndSaveMessage(item.user_id, message, 'recall');
				}
			});
		}
		return ctx.apiSuccess(message);
	}
	
	

}
module.exports = ChatController;
